/**
* Copyright 2015-2016 Knowm Inc. (http://knowm.org) and contributors.
* Copyright 2011-2015 Xeiam LLC (http://xeiam.com) and contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.knowm.yank;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
/**
* This class is a Singleton that provides access to one or more connection pools defined in a Property file. When the client shuts down it should
* call the release() method to close all open connections and do other clean up.
* <p>
* This class should not be directly accessed by client code.
*
* @author timmolter
*/
public final class YankPoolManager {
private final Logger logger = LoggerFactory.getLogger(YankPoolManager.class);
private final Properties mergedSqlProperties = new Properties();
/** The singleton instance */
protected static final YankPoolManager INSTANCE = new YankPoolManager();
protected static final String DEFAULT_POOL_NAME = "yank-default";
private final Map<String, HikariDataSource> pools = new ConcurrentHashMap<String, HikariDataSource>(2);
/**
* A private constructor since this is a Singleton
*/
private YankPoolManager() {
}
/**
* Add properties for a DataSource (connection pool). Yank uses a Hikari DataSource (connection pool) under the hood, so you have to provide the
* minimal essential properties and the optional properties as defined here: https://github.com/brettwooldridge/HikariCP
* <p>
* This convenience method will create a connection pool in the default pool.
* <p>
* Note that if you call this method repeatedly, the existing default pool will be first shutdown each time.
*
* @param dataSourceProperties
*/
protected void addDefaultConnectionPool(Properties dataSourceProperties) {
createPool(DEFAULT_POOL_NAME, dataSourceProperties);
}
/**
* Add properties for a DataSource (connection pool). Yank uses a Hikari DataSource (connection pool) under the hood, so you have to provide the
* minimal essential properties and the optional properties as defined here: https://github.com/brettwooldridge/HikariCP
* <p>
* Note that if you call this method providing a poolName corresponding to an existing connection pool, the existing pool will be first shutdown.
*
* @param poolName
* @param connectionPoolProperties
*/
protected void addConnectionPool(String poolName, Properties connectionPoolProperties) {
createPool(poolName, connectionPoolProperties);
}
/**
* Creates a Hikari connection pool and puts it in the pools map.
*
* @param poolName
* @param connectionPoolProperties
*/
private void createPool(String poolName, Properties connectionPoolProperties) {
releaseConnectionPool(poolName);
// DBUtils execute methods require autoCommit to be true.
connectionPoolProperties.put("autoCommit", true);
HikariConfig config = new HikariConfig(connectionPoolProperties);
config.setPoolName(poolName);
HikariDataSource ds = new HikariDataSource(config);
pools.put(poolName, ds);
logger.info("Initialized pool '{}'", poolName);
}
/**
* Closes the default connection pool
*/
@Deprecated
protected synchronized void releaseDataSource() {
releaseDefaultConnectionPool();
}
/**
* Closes the default connection pool
*/
protected synchronized void releaseDefaultConnectionPool() {
releaseConnectionPool(DEFAULT_POOL_NAME);
}
/**
* Closes a connection pool
*
* @param poolName
*/
protected synchronized void releaseConnectionPool(String poolName) {
HikariDataSource pool = pools.get(poolName);
if (pool != null) {
logger.info("Releasing pool: {}...", pool.getPoolName());
pool.close();
}
}
/**
* Closes a connection pool
*
* @param poolName
*/
protected synchronized void releaseAllConnectionPools() {
for (HikariDataSource pool : pools.values()) {
if (pool != null) {
logger.info("Releasing pool: {}...", pool.getPoolName());
pool.close();
}
}
}
/**
* Get a connection pool
*
* @return
*/
protected HikariDataSource getConnectionPool(String poolName) {
return pools.get(poolName);
}
/**
* Get the default connection pool
*
* @return
*/
protected HikariDataSource getDefaultConnectionPool() {
return getConnectionPool(DEFAULT_POOL_NAME);
}
protected void addSQLStatements(Properties sqlProperties) {
this.mergedSqlProperties.putAll(sqlProperties);
}
/**
* @return the mergedSqlProperties
*/
protected Properties getMergedSqlProperties() {
return mergedSqlProperties;
}
}